/*!
 *  \file	test-random-numbers.cpp
 *  \brief	Main per testare le varie distribuzioni di probabilita`
 *
 * Questo programma testa le varie distribuzioni di probabilita` su un
 * campione di numeri pseudo-casuali
 *
 *  \author     Davide Scola <S2299453@studenti.unige.it>
 *  \author	Minetti Alberto <S3064777@studenti.unige.it>
 *  \version    1.0
 *
 */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <iostream>

#include "IEntropyGenerator.hpp"
#include "TimeEntropyGenerator.hpp"
#include "DeviceEntropyGenerator.hpp"
#include "SmartEntropyGenerator.hpp"

#include "IRandomGenerator.hpp"
#include "SimpleRandomGenerator.cpp"
#include "NormalizedRandomGenerator.cpp"
#include "IntervalRandomGenerator.cpp"
#include "GaussRandomGenerator.cpp"
#include "PoissonRandomGenerator.cpp"

#include "ProbabilityDistribution.cpp"

using namespace std;


int
main( void )
{
  // Generatore di entropia
  SmartEntropyGenerator entropy;
  
  // Distribuzione uniforme
  ProbabilityDistribution< double, IntervalRandomGenerator >
    uniforme( RANDOM_NUMBERS, IntervalRandomGenerator< double >( RANDOM_XMIN, RANDOM_XMAX, entropy ) );
  
  // Distribuzione gaussiana
  ProbabilityDistribution< double, GaussRandomGenerator >
    gaussiana( RANDOM_NUMBERS, GaussRandomGenerator< double >( RANDOM_MEAN, RANDOM_VARIANCE, entropy ) );
    
  // Distribuzione poissoniana con varie medie
  unsigned int medie[] = { 10, 100, 1000 };
  
  vector< ProbabilityDistribution< double, PoissonRandomGenerator > >
    poissoniane;
  
  for(unsigned long int i = 0; i < ( sizeof( medie ) / sizeof( medie[0] ) ); ++i )
    poissoniane.push_back(
      ProbabilityDistribution< double, PoissonRandomGenerator >( RANDOM_NUMBERS, PoissonRandomGenerator< double >( medie[i], entropy ) ) );
  
  cout << "Test distribuzioni casuali con " << RANDOM_NUMBERS << " numeri." << endl << endl;
  
  cout << "Distribuzione uniforme " << endl;
  cout << "-media:\t\t" << uniforme.mean( ) << endl;
  cout << "-varianza:\t" << uniforme.variance( ) << endl;
  cout << "-deviazione:\t" << uniforme.stDeviation( ) << endl << endl;
  
  cout << "Distribuzione gaussiana" << endl;
  cout << "-media:\t\t" << gaussiana.mean( ) << endl;
  cout << "-varianza:\t" << gaussiana.variance( ) << endl;
  cout << "-deviazione:\t" << gaussiana.stDeviation( ) << endl << endl;
  
  cout << "Distribuzioni poissoniane" << endl;
  
  for(unsigned long int i = 0; i < poissoniane.size(); ++i )
  {
    cout << endl;
    cout << "-Distribuzione poissoniana con media: " << medie[i] << endl;
    cout << "--media:\t" << poissoniane[i].mean( ) << endl;
    cout << "--varianza:\t" << poissoniane[i].variance( ) << endl;
    cout << "--deviazione:\t" << poissoniane[i].stDeviation( ) << endl;
  }
  
  return 0;
}
